﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Security;
using Chaine.Models;
using System.Net.Mail;
using Chaine.DAO;
using MongoDB.Bson;
using System.Configuration;
using Chaine.Content;

namespace Chaine.Controllers
{
    public class AccountController : Controller
    {

        //
        // GET: /Account/LogIn

        public ActionResult LogIn()
        {
            return View();
        }

        //
        // POST: /Account/LogIn

        [HttpPost]
        public ActionResult LogIn(LogOnModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                if (Membership.ValidateUser(model.UserName, model.Password))
                {
                    var register = AccountManager.GetRegister(model.UserName);
                    if (!register.EmailIsValidated)
                    {
                        ModelState.AddModelError("IsEmailValidated", "");
                        TempData["RegisterID"] = register.Id.ToString();
                    }
                    if (register.EmailIsValidated && !register.IsChecked)
                        ModelState.AddModelError("IsChecked", "");
                    if (!ModelState.IsValid)
                        return View(model);
                    FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
                    if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
                        && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
                    {
                        return Redirect(returnUrl);
                    }
                    else
                    {
                        return RedirectToAction("Index", "Home");
                    }
                }
                else
                {
                    ModelState.AddModelError("WrongUserNameOrPassword", "");
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        //
        // GET: /Account/LogOff

        public ActionResult LogOff()
        {
            FormsAuthentication.SignOut();

            return RedirectToAction("Index", "Home");
        }

        //
        // GET: /Account/Register

        public ActionResult Register()
        {
            return View();
        }

        //
        // POST: /Account/Register

        [HttpPost]
        public ActionResult Register(RegisterModel model)
        {
            if (string.IsNullOrEmpty(model.Mobile))
                ModelState.AddModelError("Mobile", "Mobile is required.");
            if (string.IsNullOrEmpty(model.RealName))
                ModelState.AddModelError("RealName", "Real name is required.");
            try
            {
                var email = new MailAddress(model.Email);
            }
            catch
            {
                ModelState.AddModelError("Email", "Email need right format.");
            }
            if (string.IsNullOrEmpty(model.Nationality))
                ModelState.AddModelError("Nationality", "Nationality is required.");
            if (string.IsNullOrEmpty(model.Gender))
                ModelState.AddModelError("Gender", "Gender is required.");
            if (string.IsNullOrEmpty(model.Address))
                ModelState.AddModelError("Address", "Address is required.");
            if (string.IsNullOrEmpty(model.PostCode))
                ModelState.AddModelError("PostCode", "PostCode is required.");


            if (ModelState.IsValid)
            {
                // Attempt to register the user
                MembershipCreateStatus createStatus;
                Membership.CreateUser(model.UserName, model.Password, model.Email, null, null, true, null, out createStatus);


                if (createStatus == MembershipCreateStatus.Success)
                {

                    AccountManager.CreateRegister(model);
                    EmailManager.SendRegisterConfirmEmail(model);
                    EmailManager.SendAlertNewMemberEmail();
                    TempData["send-success"] = "";
                    return RedirectToAction("RegisterSuccess", new { id = model.Id.ToString() });
                }
                else
                {
                    if (createStatus.ToString().ToLower().Contains("username"))
                        ModelState.AddModelError("UserName", ErrorCodeToString(createStatus));
                    if (createStatus.ToString().ToLower().Contains("password"))
                        ModelState.AddModelError("Password", ErrorCodeToString(createStatus));
                    if (createStatus.ToString().ToLower().Contains("email"))
                        ModelState.AddModelError("Email", ErrorCodeToString(createStatus));

                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        public ActionResult RegisterSuccess(string id)
        {
            var register = AccountManager.GetRegister(ObjectId.Parse(id));
            return View("~/views/account/registersuccess.cshtml", register);
        }

        public ActionResult ResendValidationEmail(string id)
        {
            //发送邮件
            var register = AccountManager.GetRegister(ObjectId.Parse(id));
            EmailManager.SendRegisterConfirmEmail(register);

            TempData["send-success"] = "";
            return RedirectToAction("RegisterSuccess", new { id = id });
        }

        /// <summary>
        /// 验证email
        /// system/Account/EmailValidate/5030eeeeb7ed221b14badd98
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ActionResult EmailValidate(string id)
        {
            AccountManager.ValidateEmail(ObjectId.Parse(id));
            TempData["validate-email-success"] = "";
            return RedirectToAction("Login");
        }

        //
        // GET: /Account/ChangePassword

        [Authorize]
        public ActionResult ChangePassword()
        {
            return View();
        }

        //
        // POST: /Account/ChangePassword

        [Authorize]
        [HttpPost]
        public ActionResult ChangePassword(ChangePasswordModel model)
        {
            if (ModelState.IsValid)
            {

                // ChangePassword will throw an exception rather
                // than return false in certain failure scenarios.
                bool changePasswordSucceeded;
                try
                {
                    MembershipUser currentUser = Membership.GetUser(User.Identity.Name, true /* userIsOnline */);
                    changePasswordSucceeded = currentUser.ChangePassword(model.OldPassword, model.NewPassword);
                }
                catch (Exception)
                {
                    changePasswordSucceeded = false;
                }

                if (changePasswordSucceeded)
                {
                    return RedirectToAction("ChangePasswordSuccess");
                }
                else
                {
                    ModelState.AddModelError("", "The current password is incorrect or the new password is invalid.");
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        //
        // GET: /Account/ChangePasswordSuccess

        public ActionResult ChangePasswordSuccess()
        {
            return View();
        }

        public ActionResult CreateRootAccount()
        {
            return View("~/views/account/createrootaccount.cshtml");
        }

        [HttpPost]
        public ActionResult CreateRootAccount(RegisterModel model)
        {
            if (string.IsNullOrEmpty(model.Mobile))
                ModelState.AddModelError("Mobile", "Mobile is required.");
            if (string.IsNullOrEmpty(model.RealName))
                ModelState.AddModelError("RealName", "Real name is required.");
            try
            {
                var email = new MailAddress(model.Email);
            }
            catch
            {
                ModelState.AddModelError("Email", "Email need right format.");
            }
            if (string.IsNullOrEmpty(model.Nationality))
                ModelState.AddModelError("Nationality", "Nationality is required.");
            if (string.IsNullOrEmpty(model.Gender))
                ModelState.AddModelError("Gender", "Gender is required.");
            if (string.IsNullOrEmpty(model.Address))
                ModelState.AddModelError("Address", "Address is required.");
            if (string.IsNullOrEmpty(model.PostCode))
                ModelState.AddModelError("PostCode", "PostCode is required.");


            if (ModelState.IsValid)
            {
                // Attempt to register the user
                MembershipCreateStatus createStatus;
                Membership.CreateUser(model.UserName, model.Password, model.Email, null, null, true, null, out createStatus);

                if (createStatus == MembershipCreateStatus.Success)
                {
                    model.IsChecked = true;
                    model.EmailIsValidated = true;
                    AccountManager.CreateRegister(model);
                    //增加权限
                    AccountManager.AddAdminRole(model.Id);
                    return RedirectToAction("Login");
                }
                else
                {
                    if (createStatus.ToString().ToLower().Contains("username"))
                        ModelState.AddModelError("UserName", ErrorCodeToString(createStatus));
                    if (createStatus.ToString().ToLower().Contains("password"))
                        ModelState.AddModelError("Password", ErrorCodeToString(createStatus));
                    if (createStatus.ToString().ToLower().Contains("email"))
                        ModelState.AddModelError("Email", ErrorCodeToString(createStatus));

                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }
        [HttpPost]
        public ActionResult resetPassword(String email)
        {
            TempData["result"] = "failure";

            if (string.IsNullOrEmpty(email))
            {
                ModelState.AddModelError("email", "please input your email!");
            }
            else
            {
                try
                {
                    var email_temp = new MailAddress(email);
                }
                catch
                {
                    ModelState.AddModelError("email", "please input the right format.");
                }
                if (ModelState.IsValid)
                {
                    //获取当前用户
                    string username = Membership.GetUserNameByEmail(email);
                    if (!string.IsNullOrEmpty(username))
                    {
                        //产生连接
                        //url+邮箱+过期时间

                        string temp = email + ";" + DateTime.Now.AddDays(1).ToFileTime();//过期时间为一天

                        temp = Encryption.DesEncrypt(temp, Encryption.encryptKey);

                        string url = ConfigurationManager.AppSettings["Home"] + "/system/account/emailresetpassword?info=" + temp;

                        string title = "please reset your password now";

                        string content = "if you want to reset your password,please click the follow url : <br/><br/>" +
                                                    "<a href='" + url + "'>" + url + "</a>";

                        MailAddress toEmail = new MailAddress(email);

                        EmailManager.SendCommonEmail(toEmail, title, content);

                        TempData["result"] = "success";

                    }
                    else
                    {
                        ModelState.AddModelError("email", "the email is not exist，please input again");
                    }
                }
            }
            return View("ResetPassword");
        }

        public ActionResult resetPassword()
        {

            return View("ResetPassword");
        }
        [HttpGet]
        public ActionResult emailresetpassword(string info)
        {
            try
            {
                string temp = Encryption.DesDecrypt(info, Encryption.encryptKey);
                //对字符串分解且
                string[] temps = temp.Split(';');

                //验证解析后的格式是否正确
                MailAddress email_temp = new MailAddress(temps[0]);
                DateTime expiredTime = DateTime.FromFileTime(long.Parse(temps[1]));

                if (DateTime.Now > expiredTime)
                {
                    //如果当前时间大于过期时间，则表示过期
                    TempData["error"] = "该url已经过期";
                }
                else
                {
                    //验证邮箱是否存在
                    var username = Membership.GetUserNameByEmail(temps[0]);
                    if (string.IsNullOrEmpty(username))
                    {
                        throw new Exception("该email不存在用户");
                    }
                    else
                    {
                        ViewData["username"] = username;
                    }
                }
            }
            catch (Exception)
            {
                TempData["error"] = "该url存在错误";
            }
            return View("ResetPasswordInput");
        }

        [HttpPost]
        public ActionResult emailresetpassword(ChangePasswordModel model)
        {

            //取消old password 的验证
            ModelState.Remove("OldPassword");

            //验证用户新输入的密码
            if (ModelState.IsValid)
            {
                //如果验证通过
                string username = Request.Form["username"];//获取username
                MembershipUser user = Membership.GetUser(username);//根据用户名获取该用户
                user.ChangePassword(user.GetPassword(), model.NewPassword);//修改新密码
                return View("ResetPasswordSuccess");
            }
            else
            {

                return View("ResetPasswordInput");
            }
        }

        public ActionResult SendTestEmail()
        {
            return View("~/views/account/sendtestemail.cshtml");
        }

        [HttpPost]
        public ActionResult SendTestEmail(FormCollection form)
        {
            var to = form["to"];
            var subject = form["subject"];
            var content = form["content"];
            EmailManager.SendCommonEmail(new MailAddress(to), subject, content);
            return View("~/views/account/sendtestemail.cshtml");
        }

        #region Status Codes
        private static string ErrorCodeToString(MembershipCreateStatus createStatus)
        {
            // See http://go.microsoft.com/fwlink/?LinkID=177550 for
            // a full list of status codes.
            switch (createStatus)
            {
                case MembershipCreateStatus.DuplicateUserName:
                    return "User name already exists. Please enter a different user name.";

                case MembershipCreateStatus.DuplicateEmail:
                    return "A user name for that e-mail address already exists. Please enter a different e-mail address.";

                case MembershipCreateStatus.InvalidPassword:
                    return "The password provided is invalid. Please enter a valid password value.";

                case MembershipCreateStatus.InvalidEmail:
                    return "The e-mail address provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.InvalidAnswer:
                    return "The password retrieval answer provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.InvalidQuestion:
                    return "The password retrieval question provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.InvalidUserName:
                    return "The user name provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.ProviderError:
                    return "The authentication provider returned an error. Please verify your entry and try again. If the problem persists, please contact your system administrator.";

                case MembershipCreateStatus.UserRejected:
                    return "The user creation request has been canceled. Please verify your entry and try again. If the problem persists, please contact your system administrator.";

                default:
                    return "An unknown error occurred. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
            }
        }
        #endregion
    }
}
